import logging
import allure
import jsonpath
from utils.send_request import send_jdbc_request


# 核心步骤3：处理断言
@allure.step("3.HTTP响应断言")
def http_assert(case, res):
    expected = eval(case["expected"])  # 不管有没有校验字段，预期结果是一定有的。

    if case["check"]:
        check = eval(case["check"])
        for x, y in zip(check, expected):
            result = jsonpath.jsonpath(res.json(), f"$..{x}")[0]
            logging.info(f"3.HTTP响应断言内容：实际结果({result}) == 预期结果({y})")  # 日志不能写在assert后面。因为如果断言有问题，就不会执行断言后面的代码了。
            assert result == y  # 类比jmeter中的 json断言

        # result = jsonpath.jsonpath(res.json(), case["check"])[0]
        # logging.info(f"3.HTTP响应断言内容：实际结果({result}) == 预期结果({case["expected"]})")   # 日志不能写在assert后面。因为如果断言有问题，就不会执行断言后面的代码了。
        # assert result == case["expected"]  # 类比jmeter中的 json断言
    else:
        for y in expected:  # 这条一定要写，因为之前if语句中提到的y不会在这个else分支沿用。
            logging.info(f"3.HTTP响应断言内容：预期结果({y}) in 实际结果({res.text})")
            assert str(y) in res.text  # 类比jmeter中的 响应断言


# @allure.step("3.JDBC响应宣言")
# http请求不管怎样，都会有http断言；但数据库断言不一定会有。
# 如果在这个函数外面加上装饰器，那么无论一个http请求是否需要JDBC断言，都会在allure报告中展示出来。这是不合理的。
def jdbc_assert(case):
    if case["sql_check"] and case["sql_expected"]:
        with allure.step("3.JDBC响应宣言"):  # 用于函数内部，在报告中不会显示传参。 # 用这个比较好。先判断数据库单眼相关字段是否存在；如果存在，再在allure中展示。
            assert send_jdbc_request(case["sql_check"]) == case["sql_expected"]
